/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "log.h"
#include "camera.h"
#include "wpa_work.h"
#include "local_net_udp.h"
#include "local_net_communication.h"
#include "cJSON.h"
#include "interface.h"

#include <algorithm>
#include <cstring>
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <unistd.h>
#include <cstring>
#include <cstdio>

using namespace std;

static const char *g_easyPrModlePath = "/userdata/model";

static bool  g_runAiSwitch = false;

static int8_t msgRecv(const char *msg)
{
    static int runThread = 0;
    int ret;
    if (!msg) {
        return -1;
    }

    int8_t openFlag = 0;
    cJSON *unicastJson = cJSON_Parse(msg);
    if (!unicastJson) {
        return -1;
    }
    LOG_I("App recv msg: [%s]", msg);
    cJSON *params = cJSON_GetObjectItem(unicastJson, "params");
    if (!params) {
        LOG_E("params is null!");
        cJSON_Delete(unicastJson);
        return -1;
    }
    SAMPLE_INFO("runt that ");
    cJSON *boolOpenJson = cJSON_GetObjectItem(params, "detectResult");
    if (boolOpenJson) {
        if (!strcmp("waiting", boolOpenJson->valuestring)) {
            SAMPLE_INFO("runt that ");
            if (!g_runAiSwitch) {
                g_runAiSwitch = true;
            }
            LOG_I("latch open!");
        } else {
            LOG_I("latch close!");
        }
    }
    cJSON_Delete(unicastJson);
    return 0;
}

int RunUDP(const char *location)
{
    const char *devId = "351612b65c4881b11e4383520c7307ddad5b890fba2a6c0104fecbe397234126";
    NetBroadcastPara_t selfDevInfo;
    if (memset_s(&selfDevInfo, sizeof(selfDevInfo), 0, sizeof(selfDevInfo)) < 0) {
        return -1;
    }
    if (memcpy_s(selfDevInfo.name, sizeof(selfDevInfo.name), "3516摄像头", strlen("3516摄像头") + 1) < 0) {
        return -1;
    }
    if (memcpy_s(selfDevInfo.type, sizeof(selfDevInfo.type), "camera", strlen("camera") + 1) < 0) {
        return -1;
    }
    if (memcpy_s(selfDevInfo.id, sizeof(selfDevInfo.id), devId, strlen(devId) + 1) < 0) {
        return -1;
    }
    if (memcpy_s(selfDevInfo.group, sizeof(selfDevInfo.group), location, strlen(location) + 1) < 0) {
        return -1;
    }
    SAMPLE_INFO("selfDevInfo.group->%s, gpBuf->%s", selfDevInfo.group, location);
    selfDevInfo.priority = 150;    // 150 is the priority of the device info

    selfDevInfo.publish = CreateDlist();
    selfDevInfo.subscribe = CreateDlist();
    SAMPLE_INFO("run that");
    InsertHdlist(selfDevInfo.subscribe, "carApproachDetect", strlen("carApproachDetect") + 1);
    InsertHdlist(selfDevInfo.publish, "licensePlateRecognition", strlen("licensePlateRecognition") + 1);
    InsertHdlist(selfDevInfo.publish, "latchControl", strlen("latchControl") + 1);
    if (LocalNetSelfInfoSet(&selfDevInfo)) {
        LOG_E("LocalNetSelfInfoSet failed!");
        return -1;
    }

    SAMPLE_INFO("run that");

    LocalNetMsgRecvCbReg(msgRecv);
    int ret = LocalNetInit();
    if (ret < 0) {
        SAMPLE_ERROR("localNetInit");
        return -1;
    }

    return 0;
}

static int MainLoop()
{
    int ret;
    char licensePlate[32] = {0};

    while (1) {
        sleep(1);
        if (g_runAiSwitch) {
            Beep("/sdcard/start_lpr.mp4");
            RunAICamera();
            if (memset_s(licensePlate, sizeof(licensePlate), 0, sizeof(licensePlate)) < 0) {
                return -1;
            }
            ret = GetPlateString(IMG_PATH, static_cast<char *>(licensePlate));
            SAMPLE_INFO("ret -> %d, licensePlate->%s", ret, licensePlate);
            if (ret > -1) {
                SAMPLE_INFO("licensePlate->%s", licensePlate);
                test_send_car_data(static_cast<char *>(licensePlate));
                g_runAiSwitch = false;
            } else {
                SAMPLE_ERROR("getValue");
            }
            sleep(3);    // sleep 3 senconds for one loop!
        }
    }
    return 0;
}

int main(int argc, char **argv)
{
    int ret;
    WifiInfo mWifi;
    char entryBuf[64] = {0};

    SAMPLE_INFO("run lpr_sample APP");
    sleep(5);    // sleep 5 seconds to wait system stander!

    InitCamera();
    PlateInit(g_easyPrModlePath);
    sleep(2);    // sleep 2 senconds to wait camera init ok!

    while (1) {
        Beep("/sdcard/startWpa.mp4");
        sleep(1);
        RunQRCamera();
        sleep(2);    // sleep 2 senconds to wait QRcamera run ok!

        if (memset_s(&mWifi, sizeof(mWifi), 0x00, sizeof(mWifi)) < 0) {
            break;
        }

        ret = GetScanSsidPassword(mWifi, entryBuf, sizeof(entryBuf));
        if (ret >= 0) {
            SAMPLE_INFO("will connect wifi");
            WriteWpaConfig(static_cast<char *>(mWifi.ssid), static_cast<char *>(mWifi.pwd));
            SAMPLE_INFO("the ssid ->%s, pBuf ->%s, uBuf->%s", mWifi.ssid, mWifi.pwd, entryBuf);
            WpaClientStart();
            sleep(10);    // sleep 10 senconds to wait wpaclient run ok!
            Beep("/sdcard/successWpa.mp4");
            break;
        } else {
            Beep("/sdcard/failWpa.mp4");
            SAMPLE_INFO("getScanSsidPassword is fail");
        }
    }

    ret = RunUDP(static_cast<const char *>(entryBuf));
    if (ret < 0) {
        SAMPLE_INFO("runUDP");
    }

    MainLoop();

    return 0;
}
